import 'dart:ui';

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_svg/flutter_svg.dart' as svg;
import 'package:get/get.dart';
import 'package:hixing_app/assets/r_img.dart';
import 'package:hixing_app/views/test_view/canvas_utils.dart';
import 'package:hixing_app/views/test_view/reset_test_matrix4/model/matrix4_data_model.dart';
import 'package:hixing_app/views/test_view/test_matrix4/rect_element_model.dart';
import 'package:hixing_app/views/test_view/test_matrix4/transform_vertex_model.dart';
import 'package:vector_math/vector_math_64.dart' as vector;
import 'dart:math' as math;

class NewComputedMatrix4 extends StatefulWidget {
  const NewComputedMatrix4({super.key});

  @override
  _NewComputedMatrix4State createState() => _NewComputedMatrix4State();
}

class _NewComputedMatrix4State extends State<NewComputedMatrix4> {
  // 是否锁定比例
  bool isLock = true;

  // 触摸开始的点的数据
  Offset startPosition = const Offset(0, 0);

  Offset newCenterOffset = const Offset(0, 0);

  // 点击矩形列表
  List<RectInfoModel> rectList = [];

  List<svg.PictureInfo> iconSvgLockList = [];
  List<svg.PictureInfo> iconSvgUnLockList = [];

  // 当前操作事件
  CanvasEventType? eventType;

  // 定义矩阵
  Matrix4 matrix4 = Matrix4.identity();

  // 定义矩阵
  Matrix4 lastMatrix4 = Matrix4.identity();

// 定义矩阵数据，每次开始操作前，把上一次的矩阵解析出来，重新赋值到下一次的矩阵操作里面，再从新的矩阵操作里面执行变换数据
  Matrix4DataModel matrix4Data = Matrix4DataModel(
      dx: 100,
      dy: 100,
      scaleX: 1,
      scaleY: 1,
      rotationAngle: 0,
      skewX: 0.0,
      skewY: 0.0);

  Size imgSize = const Size(50, 100);
  Size iconSize = const Size(30, 30);
  svg.PictureInfo? imgSvgPicture;

  Future<void> loadImg() async {
    var pgSvg = await rootBundle.loadString(ImgR.imgBgPguinSVG);
    final svg.PictureInfo pictureInfo1 = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          pgSvg,
        ),
        null);
    setState(() {
      imgSvgPicture = pictureInfo1;
    });
  }

  Future<void> loadSvg() async {
    var svgDelete = await rootBundle.loadString(ImgR.imgBgDeleteIcon);
    final svg.PictureInfo pictureInfoDelete = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          svgDelete,
        ),
        null);

    var svgLock = await rootBundle.loadString(ImgR.imgBgLockIcon);
    final svg.PictureInfo pictureInfoLock = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          svgLock,
        ),
        null);

    var svgRotate = await rootBundle.loadString(ImgR.imgBgRotateIcon);
    final svg.PictureInfo pictureInfoRotate = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          svgRotate,
        ),
        null);
    var svgScale = await rootBundle.loadString(ImgR.imgBgScaleIcon);
    final svg.PictureInfo pictureInfoScale = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          svgScale,
        ),
        null);

    var svgUnlock = await rootBundle.loadString(ImgR.imgBgUnlock);
    final svg.PictureInfo pictureInfoUnlock = await svg.vg.loadPicture(
        svg.SvgStringLoader(
          svgUnlock,
        ),
        null);
    iconSvgLockList = [];
    iconSvgUnLockList = [];

    setState(() {
      iconSvgLockList.addAll([
        pictureInfoDelete,
        pictureInfoLock,
        pictureInfoRotate,
        pictureInfoScale,
      ]);
      iconSvgUnLockList.addAll([
        pictureInfoDelete,
        pictureInfoUnlock,
        pictureInfoRotate,
        pictureInfoScale,
      ]);
    });
  }

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
    matrix4 = CanvasUtils.dataToMatrix4(matrix4Data, imgSize: imgSize);
    lastMatrix4 = matrix4.clone();
    loadImg();
    loadSvg();
    SystemChrome.setPreferredOrientations(// 使设备横屏显示
        [DeviceOrientation.landscapeLeft, DeviceOrientation.landscapeRight]);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Stack(
      children: [
        Listener(
          onPointerUp: (details) {
            eventType = null;
          },
          onPointerDown: (details) {
            // 获取点击的位置
            final position = details.position;
            startPosition = position;
            lastMatrix4 = matrix4.clone();

            // 循环矩形点击域，添加点击事件
            for (var element in rectList) {
              if (element.path != null) {
                if (element.path!.contains(position)) {
                  eventType = element.type;
                  // debugPrint("element event ：${element.type}");
                  if (eventType == CanvasEventType.image) {
                  } else if (eventType == CanvasEventType.scale) {
                  } else if (eventType == CanvasEventType.lock) {
                    isLock = !isLock;
                    setState(() {});
                  } else if (eventType == CanvasEventType.rotate) {
                    // 计算当前顶点的中心 旋转的时候，使用这个新的中心点旋转
                    List<Offset> vertext = CanvasUtils.getVertex(
                        imgSize: imgSize, matrix: matrix4);

                    // 绘制图片的矩形操作框
                    Path imgTapPath = Path()
                      ..moveTo(vertext[0].dx, vertext[0].dy); // 移动到第一个顶点
                    for (int i = 1; i < vertext.length; i++) {
                      imgTapPath.lineTo(vertext[i].dx, vertext[i].dy); // 添加线段
                    }
                    imgTapPath.close(); // 封闭路径
                    vector.Vector3 currentPosition =
                        lastMatrix4.getTranslation();
                    // 把新的中心点计算进去
                    newCenterOffset = Offset(
                        currentPosition.x + imgTapPath.getBounds().center.dx,
                        currentPosition.y + imgTapPath.getBounds().center.dy);
                  }
                  break;
                }
              }
            }
          },
          onPointerMove: (details) {
            // 获取移动的位置
            final position = details.position;
            // 移动开始前的点位减去移动时的点位，计算出偏移量
            final boxPosition = position - startPosition;

            if (eventType == CanvasEventType.image) {
              print("$boxPosition");
              matrix4 = (Matrix4.identity()
                    ..translate(boxPosition.dx, boxPosition.dy)) *
                  lastMatrix4.clone();

              setState(() {});
            } else if (eventType == CanvasEventType.scale) {
              // 这里把上一次的缩放值放回去了

              double currentScaleX =
                  (imgSize.width + boxPosition.dx) / imgSize.width;
              double currentScaleY =
                  (imgSize.height + boxPosition.dy) / imgSize.height;
              if (isLock) {
                // 等比
                double equalScale = (currentScaleX + currentScaleY) / 2;
                currentScaleX = equalScale;
                currentScaleY = equalScale;
              }

              matrix4 = lastMatrix4.clone()
                ..scale(currentScaleX, currentScaleY);
              setState(() {});
            } else if (eventType == CanvasEventType.rotate) {
              // 求出初始坐标跟移动坐标后的方位角
              final angle = math.atan2(boxPosition.dy, boxPosition.dx);

              matrix4 = (Matrix4.identity()
                    ..translate(newCenterOffset.dx, newCenterOffset.dy)
                    ..rotateZ(angle)
                    ..translate(-newCenterOffset.dx, -newCenterOffset.dy)) *
                  lastMatrix4.clone();

              setState(() {});
            }
          },
          child: CustomPaint(
            size: Size.infinite,
            painter: MyCustomPainter(
                matrix4: matrix4,
                eventType: eventType,
                svgIconList: isLock ? iconSvgLockList : iconSvgUnLockList,
                rectList: rectList,
                newCenterOffset: newCenterOffset,
                imgPicture: imgSvgPicture,
                imgSize: imgSize,
                iconSize: iconSize),
          ),
        ),
        Positioned(
          top: 30,
          left: 30,
          child: GestureDetector(
            onTap: () {
              Get.back();
            },
            child: Container(
              padding: const EdgeInsets.all(10),
              decoration: BoxDecoration(
                  color: Colors.black26,
                  borderRadius: BorderRadius.circular(40)),
              child: const Icon(
                Icons.arrow_back,
                color: Colors.yellowAccent,
                size: 18,
              ),
            ),
          ),
        ),
        Positioned(
          top: 30,
          right: 120,
          child: GestureDetector(
            onTap: () {
              isLock = !isLock;
              setState(() {});
            },
            child: Container(
              padding: const EdgeInsets.all(10),
              decoration: BoxDecoration(
                  color: Colors.black26,
                  borderRadius: BorderRadius.circular(40)),
              child: Text(isLock ? '解锁' : '锁定'),
            ),
          ),
        ),
        Positioned(
          top: 30,
          right: 200,
          child: GestureDetector(
            onTap: () {
              Matrix4DataModel data = CanvasUtils.matrix4ToData(matrix4);
              print("${data.toJson()}");
              setState(() {});
            },
            child: Container(
              padding: const EdgeInsets.all(10),
              decoration: BoxDecoration(
                  color: Colors.black26,
                  borderRadius: BorderRadius.circular(40)),
              child: const Text('矩阵解析'),
            ),
          ),
        ),
      ],
    ));
  }
}

class MyCustomPainter extends CustomPainter {
  MyCustomPainter(
      {required this.matrix4,
      required this.imgPicture,
      required this.imgSize,
      required this.rectList,
      required this.eventType,
      required this.newCenterOffset,
      required this.svgIconList,
      required this.iconSize});

  final Matrix4 matrix4;
  final svg.PictureInfo? imgPicture;
  final Size imgSize;
  final Size iconSize;
  List<RectInfoModel> rectList;
  List<svg.PictureInfo> svgIconList;
  final CanvasEventType? eventType;
  final Offset newCenterOffset;

  @override
  void paint(Canvas canvas, Size size) {
    // TODO: implement paint
    rectList.clear();
    Rect imgRect = Rect.fromLTWH(0, 0, imgSize.width, imgSize.height);
    Paint paint = Paint();
    CanvasUtils.drawGrid(canvas, paint, size);
    CanvasUtils.drawCoor(canvas, paint, size);
    canvas.save();
    canvas.transform(matrix4.storage);
    if (imgPicture != null) {
      // 绘制企鹅 svg  尺寸是imgSize
      CanvasUtils.drawResizeSvg(
          canvas, imgPicture!.picture, imgSize, imgPicture!.size,
          color: null);
    }
    canvas.restore();

    // 绘制操作
    drawAction(canvas: canvas, paint: paint);
  }

  drawAction({required Canvas canvas, required Paint paint}) {
    canvas.save();
    // 计算四个顶点的当前位置
    List<Offset> vertext =
        CanvasUtils.getVertex(imgSize: imgSize, matrix: matrix4);

    // 把给点位坐标添加命名
    TransformVertexModel transformVertex = TransformVertexModel(
      topLeft: vertext[0],
      topRight: vertext[1],
      bottomRight: vertext[2],
      bottomLeft: vertext[3],
    );

    // 获取dx，dy的值
    Matrix4DataModel matrix4Data = CanvasUtils.matrix4ToData(matrix4);

    // 绘制图片的矩形操作框
    Path imgTapPath = Path()..moveTo(vertext[0].dx, vertext[0].dy); // 移动到第一个顶点
    for (int i = 1; i < vertext.length; i++) {
      imgTapPath.lineTo(vertext[i].dx, vertext[i].dy); // 添加线段
    }
    imgTapPath.close(); // 封闭路径
    //把dx dy 偏移量加回去
    debugPrint("矩阵变换后的盒子${imgTapPath.getBounds().center}");

    imgTapPath = imgTapPath.shift(Offset(matrix4Data.dx, matrix4Data.dy));
    // 绘制矩形
    paint
      ..color = Colors.orangeAccent
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;
    // canvas.translate(50, 200);
    canvas.drawPath(imgTapPath, paint);
    rectList.add(RectInfoModel(
        rect: Rect.zero, path: imgTapPath, type: CanvasEventType.image));

    // 绘制一个不旋转的矩形
    Rect centerToRect = imgTapPath.getBounds();

    canvas.drawRect(centerToRect, paint..color = Colors.purple);

    if (svgIconList.isNotEmpty) {
      drawActionIcon(
          canvas: canvas,
          paint: paint,
          eventType: CanvasEventType.scale,
          vertex: transformVertex.bottomRight,
          svgIcon: svgIconList[3],
          matrix4Data: matrix4Data);

      drawActionIcon(
          canvas: canvas,
          paint: paint,
          eventType: CanvasEventType.rotate,
          vertex: transformVertex.topRight,
          svgIcon: svgIconList[2],
          matrix4Data: matrix4Data);

      drawActionIcon(
          canvas: canvas,
          paint: paint,
          eventType: CanvasEventType.lock,
          vertex: transformVertex.topLeft,
          svgIcon: svgIconList[1],
          matrix4Data: matrix4Data);

      drawActionIcon(
          canvas: canvas,
          paint: paint,
          eventType: CanvasEventType.delete,
          vertex: transformVertex.bottomLeft,
          svgIcon: svgIconList[0],
          matrix4Data: matrix4Data);
    }

    canvas.restore();
  }

  drawActionIcon({
    required Canvas canvas,
    required Paint paint,
    required CanvasEventType eventType,
    required svg.PictureInfo svgIcon,
    required Offset vertex,
    required Matrix4DataModel matrix4Data,
  }) {
    canvas.save();
    Matrix4 iconRotateMatrix = Matrix4.identity()
      ..rotateZ(matrix4Data.rotationAngle);
    // 绘制右上角缩放的操作按钮
    Path iconPath;
    iconPath = Path()..moveTo(0, 0); // 移动到第一个顶点
    if (eventType == CanvasEventType.scale) {
      iconPath
        ..relativeLineTo(30, 0)
        ..relativeLineTo(0, 30)
        ..relativeLineTo(-30, 0);
    } else if (eventType == CanvasEventType.rotate) {
      iconPath
        ..relativeLineTo(30, 0)
        ..relativeLineTo(0, -30)
        ..relativeLineTo(-30, 0);
    } else if (eventType == CanvasEventType.lock) {
      iconPath
        ..relativeLineTo(-30, 0)
        ..relativeLineTo(0, -30)
        ..relativeLineTo(30, 0);
    } else {
      iconPath
        ..relativeLineTo(-30, 0)
        ..relativeLineTo(0, 30)
        ..relativeLineTo(30, 0);
    }

    iconPath.close(); // 封闭路径

    //旋转icon
    iconPath = iconPath.transform(iconRotateMatrix.storage);
    //把dx dy 偏移量加回去
    iconPath = iconPath
        .shift(Offset(matrix4Data.dx + vertex.dx, matrix4Data.dy + vertex.dy));

    paint
      ..color = Colors.red
      ..style = PaintingStyle.stroke
      ..strokeWidth = 2.0;

    canvas.drawPath(
        iconPath,
        paint
          ..style = PaintingStyle.fill
          ..color = Colors.black45);

    canvas.translate(iconPath.getBounds().center.dx - iconSize.width / 2 + 5,
        iconPath.getBounds().center.dy - iconSize.height / 2 + 5);
    CanvasUtils.drawResizeSvg(
        canvas, svgIcon.picture, const Size(20, 20), svgIcon.size,
        color: Colors.white);
    rectList
        .add(RectInfoModel(rect: Rect.zero, path: iconPath, type: eventType));
    canvas.restore();
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    // TODO: implement shouldRepaint
    return true;
  }
}
